package com.smzd.framework.config.handlers;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;

import com.smzd.framework.sso.SessionBasedRedirectRequest;
import com.smzd.framework.system.business.MeetingService;
import com.smzd.framework.system.business.UserService;
import com.smzd.framework.system.domain.Meeting;
import com.smzd.framework.system.domain.User;
import com.smzd.framework.utils.JsonHelper;
import com.smzd.framework.utils.MeetingSessionHolder;
import com.smzd.framework.utils.Privilege;
import com.smzd.framework.utils.URIStacks;

public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    @Autowired
    private UserService userService;
    @Autowired
    private MeetingService meetingService;

    RequestCache requestCache = new HttpSessionRequestCache();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        User user = (User) authentication.getPrincipal();
        System.out.println("登录用户：" + user);
        assert (user != null);
        String method = request.getParameter("_method");
        boolean json = method != null && "json".equalsIgnoreCase(method);
        HttpSession session = request.getSession();
        session.setAttribute(MeetingSessionHolder.KEY_LOGIN_USER, user);
        System.out.println("SessionHolder保存用户" + user);

        String base = request.getContextPath();
        // 处理应用被配置成为根应用的情形，此时获得的base为“/”，如果完成下面的拼接，将成为//workspace/nomeeting
        if (base.length() == 1) {
            base = "";
        }

        Meeting meeting = null;
        if (user.getType() == User.USER_TYPE_MEETING_MANAGER) {// 普通会务管理员
            meeting = meetingService.getItemById(user.getOwner().getId());
            user.setOwner(meeting);
            session.setAttribute(MeetingSessionHolder.KEY_MEETING, meeting);
            Privilege privilege = userService.getPrivilegeForUser(user);
            session.setAttribute(MeetingSessionHolder.KEY_PRIVILEGE, privilege);
            System.out.println("SessionHolder保存权限" + privilege);
        } else if (user.getType() == User.USER_TYPE_MEETING_OWNER) {// 会务负责人
            List<Meeting> meetings = meetingService.getMeetingsByOwnerId(user.getId());
            if (meetings == null || meetings.size() == 0) {
                // 尚没有会务被建立
                session.setAttribute(MeetingSessionHolder.KEY_MEETING, null);
                if (json) {
                    String jsonStr = getNoMeetingJsonString(request, response);
                    returnJson(response, jsonStr);
                } else {
                    beforeRedirect(request, response, authentication);
                    response.sendRedirect(base + "/workspace/nomeeting");
                }
                return;
            } else if (meetings.size() == 1) {
                // 就此一个，不用选会
                meeting = meetings.get(0);
                meeting.setOwner(user);
                session.setAttribute(MeetingSessionHolder.KEY_MEETING, meeting);
                System.out.println("SessionHolder保存会务" + meeting);
                Privilege privilege = userService.getPrivilegeForOwner(meeting);
                session.setAttribute(MeetingSessionHolder.KEY_PRIVILEGE, privilege);
                System.out.println("SessionHolder保存权限" + privilege);
            } else {
                // 必须进行选会了
                session.setAttribute(MeetingSessionHolder.KEY_MEETING_LIST, meetings);
                if (json) {
                    String jsonStr = getTooManyMeetingsJsonString(request, response);
                    returnJson(response, jsonStr);
                } else {
                    beforeRedirect(request, response, authentication);
                    response.sendRedirect(base + "/workspace/meetings");
                }
                return;
            }
        }
        URIStacks stacks = (URIStacks) session.getAttribute(URIStacks.URISTACKS_SESSION_KEY);
        SavedRequest saved;
        if (stacks == null || stacks.size() <= 0) {// 没有的话，直接按照原先的流程走
            if (!beforeRedirect(request, response, authentication)) {
                if (json) {
                    saved = (SavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST");
                    String jsonStr = getSuccessJsonString(request, response, saved.getRedirectUrl());
                    returnJson(response, jsonStr);
                } else {
                    super.onAuthenticationSuccess(request, response, authentication);
                }
            }
        } else {
            saved = stacks.pop();
            if (saved instanceof SessionBasedRedirectRequest) {
                session.removeAttribute("SPRING_SECURITY_SAVED_REQUEST");
                session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
                if (json) {
                    String jsonStr = getSuccessJsonString(request, response, saved.getRedirectUrl());
                    returnJson(response, jsonStr);
                } else {
                    response.sendRedirect(saved.getRedirectUrl());
                }
            } else {
                session.setAttribute("SPRING_SECURITY_SAVED_REQUEST", saved);
                if (!beforeRedirect(request, response, authentication)) {
                    if (json) {
                        String jsonStr = getSuccessJsonString(request, response, saved.getRedirectUrl());
                        returnJson(response, jsonStr);
                    } else {
                        super.onAuthenticationSuccess(request, response, authentication);
                    }
                }
            }
        }

    }

    protected boolean beforeRedirect(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) {
        return false;
    }

    protected String getSuccessJsonString(HttpServletRequest request, HttpServletResponse response, String redirect_url) {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(MeetingSessionHolder.KEY_LOGIN_USER);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("status", 200);
        Map<String, Object> userMap = new HashMap<String, Object>();
        userMap.put("id", user.getId());
        userMap.put("name", user.getName());
        map.put("user", userMap);
        map.put("redirect_url", redirect_url);
        return JsonHelper.getSuccessJsonString(map);
    }

    protected String getTooManyMeetingsJsonString(HttpServletRequest request, HttpServletResponse response) {
        return JsonHelper.getFailJsonString("code", 2, "你需要选则一个会务。");
    }

    protected String getNoMeetingJsonString(HttpServletRequest request, HttpServletResponse response) {
        return JsonHelper.getFailJsonString("code", 0, "你的会务没有准备好。");
    }

    protected void returnJson(HttpServletResponse response, String json) throws IOException {
        response.getWriter().write(json);
    }
}
